import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.List;

public class TestDrive {
    interface TestForFile {
        /**
         * 对指定源代码进行测试，返回是否通过测试
         *
         * @param fileName 测试的源代码文件
         * @return 是否通过测试
         */
        boolean todo(String fileName);

        String getName();

    }

    static class LexTest implements TestForFile {
        static String symbolToString(java_cup.runtime.Symbol symbol) {
            return String.format("%s: %s", OberonSymbol.terminalNames[symbol.sym], symbol.value);
        }

        @Override
        public boolean todo(String fileName) {
            try {
                OberonScanner scanner = new OberonScanner(new FileReader(fileName));
                try {
                    do {
                        java_cup.runtime.Symbol symbol = scanner.next_token();
                        System.out.println(symbolToString(symbol));
                    } while (!scanner.yyatEOF());
//                } catch (LexicalException e) {
//                    System.out.printf("发生词法错误，行：%d，列：%d\n", scanner.getLine(), scanner.getColumn());
//                    System.out.println(e.getMessage());
//                    return false;
                } catch (Exception e) {
                    System.out.printf("发生词法错误，行：%d，列：%d\n", scanner.getLine(), scanner.getColumn());
                    System.out.println(e.getMessage());
                    return false;
                }
            } catch (FileNotFoundException e) {
                System.out.printf("未找到文件：\"%s\"\n", fileName);
                return false;
            }
            return true;
        }

        @Override
        public String getName() {
            return "词法分析";
        }
    }

    static class syntaxTest implements TestForFile {

        @Override
        public boolean todo(String fileName) {
            try {
                OberonParser parser = new OberonParser(new OberonScanner(new FileReader(fileName)));
                try {
                    parser.parse();
//                } catch (OberonException ex) {
//                    System.out.println("语法分析异常");
//                    System.out.println(ex.getMessage());
                } catch (Exception ex) {
                    System.out.printf("发生语法错误，行：%d，列：%d\n", parser.getLine(), parser.getColumn());
                    System.out.println(ex.getMessage());
                    return false;
                }
            } catch (FileNotFoundException e) {
                System.out.printf("未找到文件：\"%s\"\n", fileName);
                return false;
            }
            return true;
        }

        @Override
        public String getName() {
            return "语法分析";
        }
    }


    /**
     * 对文件列表中的每一个文件进行测试
     *
     * @param test  测试所使用的类
     * @param files 文件列表
     */
    static void testAll(TestForFile test, String... files) {
        String delimiter = "==================================================";
        int passCnt = 0;
        System.out.println(delimiter);
        System.out.println(test.getName() + "开始");
        for (String file : files) {
            System.out.println(delimiter);
            System.out.println("现在测试：" + file);
            if (test.todo(file)) {
                ++passCnt;
                System.out.println("通过" + test.getName());
            } else {
                System.out.println("未通过" + test.getName());
            }
        }
        System.out.println(delimiter);
        System.out.printf("测试样例数量：%d%n", files.length);
        System.out.printf("通过的测试样例数量：%d%n", passCnt);
        System.out.printf("未通过的测试样例数量：%d%n", files.length - passCnt);
        System.out.printf("通过比例：%f%n", (double) passCnt / files.length);
    }

    public static void main(String[] argv) {
        System.out.println("hello");
        String[] files;
        if (argv.length == 0) {
            files = new String[]{"../ex1/testcases/test.obr"};
        } else {
            files = argv;
        }
        testAll(new LexTest(), files);
        testAll(new syntaxTest(), files);

    }
}
